package com.alipay.sofa.award.endpoint.impl;

import com.alibaba.common.lang.StringUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.alipay.sofa.award.biz.service.config.AwardConfigurationProperties;
import com.alipay.sofa.award.biz.service.facade.ActivityTimeFacade;
import com.alipay.sofa.award.biz.service.facade.UserInfoFacade;
import com.alipay.sofa.award.common.dal.dataobject.UserInfo;
import com.alipay.sofa.award.endpoint.constants.HeaderKeyConstants;
import com.alipay.sofa.award.endpoint.exception.AuthErrorCodeDescImpl;
import com.alipay.sofa.award.endpoint.exception.CommonException;
import com.alipay.sofa.award.endpoint.facade.AuthFacade;
import com.alipay.sofa.award.endpoint.response.RestSampleFacadeResp;
import org.jboss.resteasy.spi.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

/**
 * AuthImpl
 *
 * @author yangguanchao
 * @since 2018/09/05
 */
public class AuthImpl implements AuthFacade {

    private static final String APP_ID          = "2018083161209050";

    private static String       appPrivateKey   = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCdyVcAdMXKKU7B9IEnrhVk5PziMCNelKutb50aDnDdUYv7zs9KoSiluNiiaTgTUjSJgtcoZAeppXjg2TArRrYpxXvQRJAYK/4Fbfq7cZDv7U/UHTLcuSqboq/+8Lzbl1S51428QCPWpoPtBTQ5vBK2QNOeIVesYqe2bqfVaGGIR0QdayUH0UvF34VN5FSue+CoV4jezRZd6X09SgozGBWPVeAwNTEOAAr4kA/B41XfjvvmCYRQTNH/FB/hN0zO8ioGgizVGjkM+HQd3QLDBjhOoEElKtrxCV2iAWfwbstwDPVBQsHdapB+pKbMW1jCmN6bRRMzTIUvkwqFO0L6Zg29AgMBAAECggEAOdBFBZDDzBAYoG6DSFO72Q0iL4pt20DkKpdD3AFAj4dKoEglofWs3BP/pHqjJkkvoNcFGPKV8C4GPXS29pRhOKr4c9Y7ae/skna6sSWqco7kehb8xO0/1GjmzaXNvTQUwkdd0oU53HOE0Trf6Oule4wDPeR/qFU5mFmxOzuUyQanlEgbKffPjtMdkAJJhevlZx8mBCASbjBiPKmg3pEpHHmB5SakDmeabrgdAfSrC7nRVu9774TYhVNy++fWXZ+YivXYo8fJUlnYQhcNMQsnfNSgWNcr7OHtNAiTVNKPFUUlEnKsiZmfzFy3u5aboaiLrHoxCtuEuLdCTNktNWtQLQKBgQDgz9d5D1LVJoqNNfq1pnQMmPazjkxMLy2QolnzTB+WSwPCpk5ci5MFtpgAqObzT8qXSW8tyXBajZQjq7ZcSpQroxBSAV+e702WoM1K21YMKsEQKS9WSvxhGOW+dEbkGI1xbo+1O/9dBpMrdkN5w3g7F6KOsyQDU5ntFAQFgIEddwKBgQCzrRoO5yjfQ0+BsTUH25H3/2x2e6AdwCEaK1zFhoroFrI65EonyriTdbuCDaKvKqOvSIL7OhVy2MBBo708EN4SZ1etCCeWVG5AY+tycAmMNKEqFOxnTHKQAhRduXUJRvimqBG33OTmy8hjwwXJsXt6BZI7nJBDeB+XCguVS1JrawKBgEb0stCt6noGQSLSz7+3utcjDHKdzi0ZkuscowFsnGemY5hzPzZsg0oBWLaUmNhg7dOURPgRpVmfaAteLh+xFlUzkXogntqeM0IAnOsskVsjv23nYd59qmzHG/Rh5OIncbVErS0Js87bvWWxXRi4fmFAU3lwx0QZhfLTJ3XJGnd/AoGAHljFRvEaASOAQTpp54rZS5azfguBTqUNsjrSr3X67hovPi0irTfbFuTSp7Of35AHF2ra3I3B46TiS/PY2VVL/LXBpDL1ZLmb6Xo24Rw1MJ4O/mmMSCIsU1BWmkHhl5CKHLPUUkaXzrdqgBcHWjqEzWY1faYC47JdO4hxzmRrZkMCgYBK21aAGsjhONbFYfUujcrPk1cbaTuU+YHPP9/kFoST8gWPAPswh3ZY5pKx+FGSDkV9RbNMxb41AeqD4QeAI09l0KyjP2SFJmmfCLKdf86/7YeZf+iQjxsmwca4QRYbySkpqheDifslR/BrKl855UMEiUEG50BEpEo3Lm6uI9t9PA==";

    private static String       alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqWs76xkOmTj0IP5Mn1vmV9+B9ikzEqndjqGKl+q+MxzzBKYSWGvthRUmRU8QKEk1z3p38o8Xkpvczzrn7zamQMUVthUdJfoXsAB9k+WN9EAKCcyS7l39yuLFSXcTLQg78suSOcQwowzdzXXuMPZ64rrKaqG4TcTNASyP7JPg2CPdN+X+XLo2BJwuv8hi7U3M0KAZ5Dk2dJ2nAVxYhRBzauKldiVCre69ceIh0VCB9HkUjqXgcegAYKjhfX80hJSv6Bt0mDqhc1CpUCEB8WPBsqn8d/hQ2K8Nh5YA88tzpRXr3z833LN8uKKbNS0bpUZ7nW2w3BwYXjp/Ka29l7mPbwIDAQAB";

    private AlipayClient        alipayClient;

    @Autowired
    private UserInfoFacade      userInfoFacade;

    @Autowired
    private ActivityTimeFacade  activityTimeFacade;

    @Autowired
    public AuthImpl(AwardConfigurationProperties awardConfigurationProperties) {
        //init
        this.alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
            awardConfigurationProperties.getAppId(),
            awardConfigurationProperties.getAppPrivateKey(), "json", "UTF-8",
            awardConfigurationProperties.getAlipayPublicKey(), "RSA2");
    }

    @Override
    public RestSampleFacadeResp<UserInfo> authUser(String authCode, HttpResponse response)
                                                                                          throws Exception {
        if (StringUtil.isBlank(authCode)) {
            throw new CommonException(AuthErrorCodeDescImpl.AUTH_CODE_BLANK_ERROR_CODE_DESC);
        }
        //token and userId
        AlipaySystemOauthTokenResponse alipaySystemOauthTokenResponse = this
            .getAccessToken(authCode);
        if (!alipaySystemOauthTokenResponse.isSuccess()) {
            throw new CommonException(AuthErrorCodeDescImpl.AUTH_TOKEN_ERROR_CODE_DESC,
                alipaySystemOauthTokenResponse.getCode(), alipaySystemOauthTokenResponse.getMsg());
        }
        String accessToken = alipaySystemOauthTokenResponse.getAccessToken();
        //get user by accessToken
        AlipayUserInfoShareResponse alipayUserInfoShareResponse = this.getUserInfo(accessToken);
        String userId = alipayUserInfoShareResponse.getUserId();
        if (StringUtil.isBlank(userId)) {
            throw new CommonException(AuthErrorCodeDescImpl.AUTH_USER_INFO_ERROR_CODE_DESC,
                alipayUserInfoShareResponse.getCode(), alipayUserInfoShareResponse.getBody());
        }

        UserInfo userInfo = this
            .convertFromAlipayUserInfoShareResponse(alipayUserInfoShareResponse);
        userInfo.setAccessToken(accessToken);
        userInfo.setRefreshToken(alipaySystemOauthTokenResponse.getRefreshToken());
        //insert or update userInfo
        this.userInfoFacade.insertOrUpdateByUserId(userInfo);
        //header added
        response.getOutputHeaders().putSingle(HeaderKeyConstants.ACCESS_TOKEN_KEY, accessToken);
        response.getOutputHeaders().putSingle(HeaderKeyConstants.USER_ID_KEY,
            alipayUserInfoShareResponse.getUserId());
        return new RestSampleFacadeResp<UserInfo>(userInfo);
    }

    private AlipaySystemOauthTokenResponse getAccessToken(String authCode)
                                                                          throws AlipayApiException {
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode(authCode);
        request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
        return alipayClient.execute(request);
    }

    private AlipayUserInfoShareResponse getUserInfo(String accessToken) throws AlipayApiException {
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        return alipayClient.execute(request, accessToken);
    }

    private UserInfo convertFromAlipayUserInfoShareResponse(AlipayUserInfoShareResponse alipayUserInfoShareResponse) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(alipayUserInfoShareResponse.getUserId());
        userInfo.setNickName(alipayUserInfoShareResponse.getNickName());
        userInfo.setAvatar(alipayUserInfoShareResponse.getAvatar());
        //now
        userInfo.setModifyTime(new Date());
        return userInfo;
    }
}
